using System;
using PhillyCodeCamp.Domain.Validation;
using PhillyCodeCamp.Infrastructure;
using PhillyCodeCamp.Services;

namespace PhillyCodeCamp.Domain
{
    public class TaxReturn : DomainObject, ITaxReturn
    {
        public decimal Income { get; private set; }
        public string UsState { get; private set; }
        public DateTime SubmissionDate { get; private set; }
        public bool IsBailedOut { get; private set; }
        private readonly ITaxRateService _taxRateService;

        public TaxReturn(
            decimal income, string usState, DateTime submissionDate, bool isBailedOut,
            ITaxRateService taxRateService) : base (Rules.Default)
        {
            Income = income;
            UsState = usState;
            SubmissionDate = submissionDate;
            IsBailedOut = isBailedOut;
            _taxRateService = taxRateService;
        }

        public TaxReturn(decimal income, string usState, DateTime submissionDate, bool isBailedOut)
            : this(income, usState, submissionDate, isBailedOut, 
            DependencyResolver.Resolve<ITaxRateService>())
        {
        }

        public decimal ComputeTax()
        {
            if (IsBailedOut) 
                return Income*_taxRateService.GetBailedOutTaxRate();

            var totalTax = ComputeUsTax() + ComputeStateTax();
            if (_taxRateService.IsSubmittingLate(SubmissionDate))
            {
                totalTax += (totalTax*_taxRateService.GetLatePaymentPercent());
            }
            return totalTax;
        }

        public decimal ComputeStateTax()
        {
            return _taxRateService.GetStateTaxRate(UsState, Income)*Income;
        }

        public decimal ComputeUsTax()
        {
            return _taxRateService.GetUsTaxRate(Income)*Income;
        }

        private sealed class Rules
        {
            private Rules()
            {

            }
            public static IBusinessRuleSet Default
            {
                get
                {
                    return new BusinessRuleSet<TaxReturn>();
                }
            }
        }

    }

}